#!/usr/bin/env python
# $Id: stdfile.py e501b84d8043 2013/07/05 07:47:14 pgurumur $
#
# Copyright (c) 2012 Prabhu Gurumurthy <pgurumur@gmail.com>
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# File generated on Sat Aug 25, 2012 @ 00:44:54

__version__  = "$Revision: e501b84d8043 $"
__author__   = "$Author: pgurumur $"
__modified__ = "$Date: 2013-07-05 07:47:14Z $"

import optparse
import os
import datetime
import sys
import time
import jinja2

from venya.lib import cmdparser, exception, stdlib

def printdate(value = 0):
   retval = None
   if value == 0:
      retval = datetime.datetime.now().strftime("%a, %B %d, %Y %T %p")
   else:
      retval = datetime.datetime.now().strftime("%D %X")

   return retval

randstring = lambda length: stdlib.randstring(length)
printenv = lambda var: os.getenv(var)

class script(cmdparser.GetOpt):
   option_list = (
         optparse.make_option("-p", "--program", type = "str",
            help = "Program version to use", dest = "program"),
         optparse.make_option("-s", "--source", type = "str",
            help = "Source template to use",
            default = "%s/apps/etc/stdfile.j2" %os.getenv("HOME"),
            dest = "source"),
         optparse.make_option("-l", "--language", type = "choice",
            help = "Name of the output file to use", dest = "language",
            choices = [ "python", "perl", "tcl", "tk", "shell", "sh", "awk",
               "sed", "c", "cpp", "c++", "cc", "lua", "sql", "html", "htm",
               "js", "javascript", "py", "pl", "jinja", "j2", "make", "bc",
               "gmake", "jinja2"]),
         optparse.make_option("-m", "--module", action = "store_true",
            help = "Enable templating for a module", default = False,
            dest = "module"),
   ) + cmdparser.GetOpt.option_list

   usage = "[ options ] filename"

   help = """
   Script to generate script file with proper license and RCS/CVS tags
   Languages supported are awk, c, cpp, lua, perl, python, sed, sh, sql and
   tcl
   The template is written using Cheetah.

   Usage is stdfile.py language -n scriptfile
   the actual filename is passed using -n option
   Example to generate a python script

   stdfile.py -l python myfirstscript.py

   if -m option is invoked, it would result in interpreter not being printed
   because the script would be treated as a module

   -s option is a default, should not be invoked ideally, because that would be
   used to source a different template

   if -p option is invoked, it should specify the version of the interpreter and
   this version would be appended to the interpreter name

   Example:
      stdfile.py -l python -p 3.3 somefile.py
   Would result in the interpreter being #!/usr/bin/env python3.3

   The new template should have the following variable defined
   interpreter, date, year and name,
   name is the filename
   """

   def __init__(self, **kwargs):
      super(script, self).__init__(**kwargs)

   @cmdparser.getopts
   def handle(self):
      if len(self.arguments[1:]) == 0:
         self.error("%s: Need filename(s) to proceed", str(self))

      opts = {}
      opts["year"] = time.strftime("%Y", time.localtime())
      if self.options.language in ('py', 'python'):
         opts["interpreter"] = "python"
      elif self.options.language in ('pl', 'perl'):
         opts["interpreter"] = "perl"
      elif self.options.language in ('tcl', 'tk'):
         opts["interpreter"] = "tclsh"
      elif self.options.language in ('sh', 'shell'):
         opts["interpreter"] = "sh"
      elif self.options.language in ('awk'):
         opts["interpreter"] = "awk"
      elif self.options.language in ('sed'):
         opts["interpreter"] = "sed"
      elif self.options.language in ('c'):
         opts["interpreter"] = "c"
      elif self.options.language in ("cpp", "c++", "cc"):
         opts["interpreter"] = "cpp"
      elif self.options.language in ("lua"):
         opts["interpreter"] = "lua"
      elif self.options.language in ("sql"):
         opts["interpreter"] = "sql"
      elif self.options.language in ("html", "htm"):
         opts["interpreter"] = "html"
      elif self.options.language in ("js", "javascript"):
         opts["interpreter"] = "javascript"
      elif self.options.language in ('jinja', 'jinja2', 'j2'):
         opts["interpreter"] = "jinja"
      elif self.options.language in ("bc"):
         opts["interpreter"] = "bc"
      elif self.options.language in ("make", "gmake"):
         opts["interpreter"] = "make"
      else:
         self.error("%s: Unknown language!", str(self))

      if self.options.program:
         opts["version"] = self.options.program
      else:
         opts["version"] = 0

      if self.options.module:
         opts["module"] = 1
      else:
         opts["module"] = 0

      env = tmpl = None
      try:
         env = jinja2.Environment(loader = jinja2.FileSystemLoader(
            os.path.dirname(self.options.source)))
         env.filters['date'] = printdate
         env.filters['randstring'] = randstring
         env.filters['env'] = printenv
         tmpl = env.get_template(os.path.basename(self.options.source))
      except jinja2.exceptions.TemplateSyntaxError as err:
         self.error("%s: %s", str(self), str(err))
      except jinja2.exceptions.TemplateNotFound as err:
         self.error("%s: cannot find template %s", str(self), str(err))
      else:
         for filename in self.arguments[1:]:
            opts["name"] = filename
            if not os.path.exists(filename):
               with open(filename, "w") as fh:
                  fh.write(tmpl.render(opts))
            else:
               self.warning("%s: filename %s already exists", str(self),
                     filename)

if __name__ == "__main__":
   std = None
   try:
      std = script(version = 0.1, args = sys.argv)
      if len(std) <= 1:
         std.printhelp()
      else:
         std.handle()
   except exception.GetOptError as err:
      print(err)
      sys.exit(1)
